using System;
using System.IO;
using System.Windows.Media;
using System.Windows;
using System.Collections.Generic;

namespace XmWinKit.Common
{
    public static class Kit
    {

        public static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child is T typedChild)
                {
                    return typedChild;
                }

                T childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                {
                    return childOfChild;
                }
            }

            return null;
        }

        // 将16进制图标代码转换为Unicode字符
        public static string ConvertIconCodeToChar(string iconCode)
        {
            if (string.IsNullOrEmpty(iconCode))
                return "";

            try
            {
                // 将16进制字符串转换为整数
                int codePoint = Convert.ToInt32(iconCode, 16);
                // 转换为字符并返回
                return char.ConvertFromUtf32(codePoint);
            }
            catch
            {
                return "";
            }
        }
        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject parent) where T : DependencyObject
        {
            if (parent == null) yield break;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);

                if (child is T t)
                    yield return t;

                foreach (var childOfChild in FindVisualChildren<T>(child))
                    yield return childOfChild;
            }
        }

        public static T FindAncestor<T>(this DependencyObject current) where T : DependencyObject
        {
            current = VisualTreeHelper.GetParent(current);

            while (current != null)
            {
                if (current is T ancestor)
                {
                    return ancestor;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            return null;
        }

        /// <summary>
        /// 使颜色变亮的辅助方法
        /// </summary>
        /// <param name="color">原始颜色</param>
        /// <param name="factor">变亮因子 (0.0-1.0)</param>
        /// <returns>变亮后的颜色</returns>
        public static Color LightenColor(Color color, double factor)
        {
            // 转换为 HSL 颜色空间
            var (h, s, l) = RgbToHsl(color);

            // 增加亮度，但不超过 1.0
            l = Math.Min(l + factor, 1.0);

            // 转回 RGB 颜色空间
            return HslToRgb(h, s, l);
        }

        /// <summary>
        /// 使颜色变暗的辅助方法
        /// </summary>
        /// <param name="color">原始颜色</param>
        /// <param name="factor">变暗因子 (0.0-1.0)</param>
        /// <returns>变暗后的颜色</returns>
        public static Color DarkenColor(Color color, double factor)
        {
            // 转换为 HSL 颜色空间
            var (h, s, l) = RgbToHsl(color);

            // 降低亮度，但不低于 0.0
            l = Math.Max(l - factor, 0.0);

            // 转回 RGB 颜色空间
            return HslToRgb(h, s, l);
        }

        /// <summary>
        /// 将 RGB 颜色转换为 HSL 颜色空间
        /// </summary>
        private static (double h, double s, double l) RgbToHsl(Color rgb)
        {
            double r = rgb.R / 255.0;
            double g = rgb.G / 255.0;
            double b = rgb.B / 255.0;

            double max = Math.Max(r, Math.Max(g, b));
            double min = Math.Min(r, Math.Min(g, b));
            double delta = max - min;

            double h = 0;
            double s = 0;
            double l = (max + min) / 2;

            if (delta != 0)
            {
                s = l < 0.5 ? delta / (max + min) : delta / (2 - max - min);

                if (max == r)
                    h = (g - b) / delta + (g < b ? 6 : 0);
                else if (max == g)
                    h = (b - r) / delta + 2;
                else
                    h = (r - g) / delta + 4;

                h /= 6;
            }

            return (h, s, l);
        }

        /// <summary>
        /// 将 HSL 颜色转换为 RGB 颜色空间
        /// </summary>
        private static Color HslToRgb(double h, double s, double l)
        {
            double r, g, b;

            if (s == 0)
            {
                r = g = b = l;
            }
            else
            {
                double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
                double p = 2 * l - q;

                r = HueToRgb(p, q, h + 1.0 / 3);
                g = HueToRgb(p, q, h);
                b = HueToRgb(p, q, h - 1.0 / 3);
            }

            return Color.FromArgb(
                255, // 完全不透明
                (byte)Math.Round(r * 255),
                (byte)Math.Round(g * 255),
                (byte)Math.Round(b * 255));
        }

        /// <summary>
        /// HSL 转 RGB 的辅助方法
        /// </summary>
        private static double HueToRgb(double p, double q, double t)
        {
            if (t < 0) t += 1;
            if (t > 1) t -= 1;

            if (t < 1.0 / 6)
                return p + (q - p) * 6 * t;
            if (t < 1.0 / 2)
                return q;
            if (t < 2.0 / 3)
                return p + (q - p) * (2.0 / 3 - t) * 6;

            return p;
        }

        /// <summary>
        /// 获取偏色后的颜色
        /// </summary>
        /// <param name="color"></param>
        /// <param name="factor"></param>
        /// <returns></returns>
        public static Color AdjustBrightness(Color color, double factor)
        {
            // 第一步：改变颜色（增加偏移量）
            byte shiftedR = (byte)Math.Min(255, color.R + 30);  // 红色偏移更多
            byte shiftedG = (byte)Math.Min(255, color.G - 10);  // 绿色略微减少
            byte shiftedB = (byte)Math.Min(255, color.B + 20);  // 蓝色适中偏移

            // 第二步：提高亮度（factor + 0.2）
            return Color.FromArgb(color.A,
                (byte)Math.Min(255, shiftedR * (factor + 0.2)),
                (byte)Math.Min(255, shiftedG * (factor + 0.2)),
                (byte)Math.Min(255, shiftedB * (factor + 0.2)));
        }

    }
}